# prevodjenje ("super" Makefile preuzet negdje na netu te doradjen)

AUTOR = Ime_Prezime
PROJEKT := $(shell basename `pwd`)
PLATFORMA = i386
DIRSKODOM := jezgra/$(PLATFORMA)/arh jezgra sucelje/kod \
		programi/pozdrav_svima programi/vrijeme programi/tipkovnica \
		programi/programski_prekidi programi/dretve programi/dogadjaji
# "\" na kraju retka kaze 'make'-u da je i redak ispod zapravo dio prethodnog
# retka, tj. da je sve jedan redak (make oba spoji u jedan);
# nema nikakvih ogranicenja na duljinu retka!

DIRSAZAGL := . sucelje jezgra/$(PLATFORMA)

# razlika izmedju "=" i ":=" je sto se sa ":=" odmah 'evaluira', dok sa "=" nosi
# dalje formulu

PREDLOSCI = ../predlosci
CDPREDLOZAK = bootcdpr
OBJDIR = izgradnja
CDSLIKA = $(OBJDIR)/$(PROJEKT).iso
BIN = $(OBJDIR)/$(PROJEKT).bin

CDRADNI := $(OBJDIR)/$(CDPREDLOZAK)
GRUBMENI := $(CDRADNI)/boot/grub/menu.lst

# sve datoteke koje treba kompajlirati: *.c, *.S
DATOTEKE := $(foreach DIR,$(DIRSKODOM),$(wildcard $(DIR)/*.c $(DIR)/*.S))

# objekti koji nastaju kompajliranjem i to u $(OBJDIR);
# napravit ce se struktura direktorija ista kao i kod kodova
OBJEKTI := $(addprefix $(OBJDIR)/, $(DATOTEKE:.c=.o))
OBJEKTI := $(OBJEKTI:.S=.asm.o)
# objekti iz .S datoteka ce imati ime koje zavrsava sa .asm.o
# tako mogu imati a.c i a.S u istom direktoriju (ako treba)

# automatsko generiranje ovisnosti - gledaju se zaglavlja (gcc sa -MMD)
OVISNOSTI := $(addprefix $(OBJDIR)/, $(DATOTEKE:.c=.d))
OVISNOSTI := $(OVISNOSTI:.S=.asm.d)

# prevodjenje u konacni program/produkt ide u 2. glavne faze:
# 1. prevodjenje u objektni oblik: cc -c ...
# 2. povezivanje (linkanje): ld ...
# jedno i drugo treba neke program i zastavice;
CC = gcc	# gcc je 'prevodioc' (kompajler) # izbjegavati ovakve komentare
LINK = ld	# ld je 'povezivac'  (linker)    # u istom redu sa postavkama!

# obzirom da stvaramo sustav od 'nule' ne zelimo da ukljuci nista iz
# nikakvih biblioteka koje gcc mozda ima, zato su zastavice malo 'cudne':
CFLAGS = -O3 -m32 -Wall -ffreestanding -nostdlib -fno-stack-protector
# -O3 kaze da optimira "jako"

# treba nam 'slika' kako posloziti sve u memoriju, a to pise u ldscript.ld
LDSKRIPTA = jezgra/$(PLATFORMA)/ldscript.ld
LDFLAGS = -O3 -melf_i386 -T $(LDSKRIPTA)

# 'direktive' koje saljemo gcc-u (preko zastavice -D npr. -D MAKRO1)
# (to se kasnije tako i ukljucuje u prevodjenje)
# rezultat toga je isti kao da smo u kodu svih datoteka koje se prevode
# napisali #define MAKRO1 itd.
# MAKRO1 moze biti i VAR=vrijednost => #define VAR vrijednost
CMAKROI := PROJEKT="\"$(PROJEKT)\"" PLATFORMA="\"$(PLATFORMA)\"" \
	AUTOR="\"$(AUTOR)\"" \
	JLOGIRAJ JLOGIRAJ_GRESKU JLOGIRAJ_UPOZORENJA #JLOGIRAJ_DETALJE 

# koji 'targeti' nisu datoteke, tj. ne generiraju datoteke
.PHONY: stvoridir brisi brisi_sve qemu


# prvi 'target' - njega ce ici raditi, ostale tek po zahtjevu
# ima dva imena: sve i all, pa ih se moze aktivirati sa:
# 1. (samo) make (obzrirom da je prvi 'target')
# 2. make sve
# 3. make all

sve all: stvoridir $(CDSLIKA)

# ovaj 'target' ima samo zadane ovisnosti, treba napraviti oba 'target'-a:
# 'stvoridir' i $(CDSLIKA)


# 'slika' datoteke sa 'OS'-om
$(CDSLIKA): $(BIN)
	@-if [ ! -e $(GRUBMENI) ]; then 			\
	echo "default 0" > $(GRUBMENI) 				;\
	echo "timeout=0" >> $(GRUBMENI)				;\
	echo "title $(PROJEKT)" >> $(GRUBMENI) 			;\
	echo "root (cd)" >> $(GRUBMENI)				;\
	echo "kernel /boot/$(PROJEKT).bin" >> $(GRUBMENI)	;\
	echo "boot" >> $(GRUBMENI)				;\
	fi;
	@cp $(BIN) $(CDRADNI)/boot/$(PROJEKT).bin
	@mkisofs -m '.svn' -J -R -b boot/grub/stage2_eltorito		\
	-no-emul-boot -boot-load-size 4 -boot-info-table -V $(PROJEKT)	\
	-A $(PROJEKT) -o $(CDSLIKA) $(CDRADNI) 2> /dev/null
	@echo
	@echo Slika sustava: $(CDSLIKA)
	@echo

# slika jezgre (ali ne na cd-u)
$(BIN): $(OBJEKTI) $(LDSKRIPTA)
	@echo [ld] $@
	@$(LINK) $(LDFLAGS) $(OBJEKTI) -o$@

# kompajliram, i usput radim "ovisnosti" (zastavica -MMD)
# (prvi put ionako moram sve kompajlirati)
# kako dobiti objekte (koji su mi potrebni za prethodni 'target'
# ... iz C datoteka (.c)
$(OBJDIR)/%.o: %.c
	@echo [cc] $< ...
	@$(CC) -c $< -o $@ -MMD $(CFLAGS) \
		$(foreach INC,$(DIRSAZAGL),-I$(INC)) \
		$(foreach MACRO,$(CMAKROI),-D $(MACRO))
# ... iz S datoteka (.S - asembler)
$(OBJDIR)/%.asm.o: %.S
	@echo [cc] $< ...
	@$(CC) -c $< -o $@ -MMD $(CFLAGS) \
		$(foreach INC,$(DIRSAZAGL),-I$(INC)) \
		$(foreach MACRO,$(CMAKROI),-D $(MACRO))

# stvori direktorije za objekte i cd
stvoridir:
	@-if [ ! -e $(OBJDIR) ]; then mkdir -p $(OBJDIR); fi;
	@-$(foreach DIR,$(DIRSKODOM), if [ ! -e $(OBJDIR)/$(DIR) ]; \
		then mkdir -p $(OBJDIR)/$(DIR); fi; )
	@-if [ ! -e $(CDRADNI) ]; then mkdir -p $(CDRADNI); \
		cp -a $(PREDLOSCI)/$(CDPREDLOZAK) $(OBJDIR)/ ; fi;

obrisi:
	@echo Brisem.
	@-rm -f $(OBJEKTI) $(OVISNOSTI)
	@-rm -f $(BIN) $(CDSLIKA)

obrisi_sve clean_all:
	@echo Brisem sve!
	@-rm -rf $(OBJDIR)
# znak @ kaze make-u da ne ispisuje naredbu koju izvodi
# pocetni minus: - kaze make-u da ne 'pukne' ako rm ne obavi svoje (javi gresku)


#pokretanje u "qemu" emulatoru
#qemu se moze instalirati na Ubuntu sa: sudo apt-get install qemu

qemu: stvoridir $(CDSLIKA)
	@echo Pokrecem...
	@-qemu -no-kvm -cdrom $(CDSLIKA)


# ako ovo nije prvo pokretanje 'make'-a, tj. postoje .d datoteke
# onda ih ukljuci - pokazuju ovisnosti tipa: a.o: a.c b.h c.h
-include $(OVISNOSTI)